const gulp = require('gulp')
const gulpShell = require('gulp-shell')
const runSequence = require('run-sequence')
const del = require('del')
const $ = require('gulp-load-plugins')()
const uglify = require('gulp-uglify-es').default
const tsc = gulpShell.task([ 'tsc' ])

const fs = require('fs')
const zip = require('gulp-zip')
const UpdateService = require('./update_service')

gulp.task('default', function () {
  runSequence(
    ['rmDist'],
    ['tsc'],
    ['uglifyJS'],
    ['buildAndcopyFrontendDistToBackend'],
    ['addManifest', 'addAssets']
  )
})
gulp.task('rmDist', function () {
  return del.bind(['**'], { force: true, cwd: './dist'})
})
gulp.task('buildAndcopyFrontendDistToBackend', gulpShell.task([
  'cd ../frontend && \
  npm install --no-audit --registry http://npm-registry.forensix.cn && \
  npm run build && \
  cp -r dist ../backend'
]))
gulp.task('tsc', tsc)
gulp.task('uglifyJS', function () {
  return gulp.src(['dist/**/*'], { base: 'dist', dot: true })
    .pipe($.if('*.js',
      uglify({
        compress: { passes: 1 },
        output: {
          beautify: false,
          preamble: '/* honglian copy right */'
        }
      })
    ))
    .on('error', function (err) {
      gulpUtil.log(gulpUtil.colors.red('[Error]'), err)
    })
    .pipe(gulp.dest('dist'))
})
gulp.task('addManifest', function () {
  return gulp.src('manifest.json')
    .pipe(gulp.dest('dist'))
})
const addAssets = function () {
  return gulp.src('src/Assets/**/*')
    .pipe(gulp.dest('dist/background/Assets'))
}
gulp.task('addAssets', addAssets)

gulp.task('watch:tsc', function () {
  const watcher = gulp.watch('src/**/*.ts')
  watcher.on('change', function (event) {
    if (event) {
      tsc()
    }
  })
})

//////////////////////////////
// do test

const testAction = function () {
  return gulp.src('test/**/*')
    .pipe(gulp.dest('dist/test'))
}
const copyManifest = function () {
  return gulp.src('manifest.json')
  .pipe(gulp.dest('dist'))
}
gulp.task('addTestFiles', testAction)

gulp.task('watch:test', function () {
  const watcher = gulp.watch(['test/**/*.js', 'src/**/*.ts', 'manifest.json'])
  watcher.on('change', function (event) {
    tsc()
    testAction()
    copyManifest()
    addAssets()
  })
})

/////////////////////////////
// do build

gulp.task('all', gulpShell.task('gulp && gulp doRestOfBuild'))

gulp.task('doRestOfBuild', function () {
  runSequence(
    'packBackendModule',
    'delTest',
  )
})

gulp.task('packBackendModule', function () {
  runSequence(
    // below for Webimager only
    ['addPackageJson'],
    ['installNeededModules'],
    ['rmPackageFiles']
  )
})

gulp.task('addPackageJson', function () {
  return gulp.src('package.json')
          .pipe(gulp.dest('dist'))
})
gulp.task('installNeededModules', gulpShell.task([
  'cd dist && npm install --production --no-audit --registry http://npm-registry.forensix.cn'
]))

gulp.task('delTest', del.bind(null, ['dist/background/Service/Test.js']))
gulp.task('rmPackageFiles', del.bind(null, ['dist/package*']))


///////////////////////////////////////////////////////////////
// deploy
const zipName = "demo.zip"
gulp.task("deploy", function () {
  runSequence(
    "pack",
    "upload"
  )
})
gulp.task("pack", function () {
  return gulp.src("dist/**/*")
    .pipe(zip(zipName))
    .pipe(gulp.dest("./"))
})
gulp.task("upload", function (cb) {
  let ACCOUNT_USER = process.env.ACCOUNT_USER
  let ACCOUNT_PASS = process.env.ACCOUNT_PASS
  let CLIENT_ID = process.env.CLIENT_ID
  let CLIENT_SECRET = process.env.CLIENT_SECRET

  if (!ACCOUNT_USER || !ACCOUNT_PASS) return cb('ACCOUNT_USER and ACCOUNT_PASS not found')
  if (!CLIENT_ID || !CLIENT_SECRET) return cb('CLIENT_ID and CLIENT_SECRET not found')
  var server = new UpdateService(CLIENT_ID, CLIENT_SECRET)
  server.login(ACCOUNT_USER, ACCOUNT_PASS, function (err) {
    if (err) return cb(err)
    fs.readFile('manifest.json', {encoding: 'UTF-8'}, function (err, content) {
      if (err) return cb(err)
      var manifest = JSON.parse(content)
      var param = [{
        type: 'extension',
        name: manifest.title,
        id: manifest._id,
        description: manifest.description,
        version: manifest.version,
        deps: manifest.require_min_version,
        path: zipName
      }]
      server.uploadComponents(param, cb)
    })
  })
})